"""
TTS应用配置管理器
"""

import os
import yaml
import logging
from dataclasses import dataclass, field
from pathlib import Path
from typing import Dict, Any, Optional, List

# 尝试导入python-dotenv，如果没有安装则跳过
try:
    from dotenv import load_dotenv
    _dotenv_available = True
except ImportError:
    _dotenv_available = False

logger = logging.getLogger(__name__)


@dataclass
class ServerConfig:
    """服务器配置"""
    host: str = "0.0.0.0"
    port: int = 8003
    debug: bool = False


@dataclass
class VolcengineConfig:
    """火山引擎配置"""
    app_id: str = ""
    access_token: str = ""
    resource_id: str = "volc.megatts.default"
    ws_url: str = "wss://openspeech.bytedance.com/api/v1/tts/ws_binary"


@dataclass
class AudioConfig:
    """音频参数配置"""
    format: str = "mp3"
    sample_rate: int = 24000
    enable_timestamp: bool = False
    speech_rate: float = 1.0
    loudness_rate: float = 1.0
    emotion: str = ""
    emotion_scale: float = 1.0


@dataclass
class ProcessingConfig:
    """处理参数配置"""
    disable_markdown_filter: bool = True
    disable_emoji_filter: bool = True
    enable_language_detector: bool = True
    silence_duration: int = 0
    explicit_language: str = ""


@dataclass
class ConnectionConfig:
    """连接参数配置"""
    timeout: int = 30
    max_retries: int = 3
    retry_delay: int = 1


@dataclass
class VoiceOption:
    """单个音色选项"""
    id: str
    name: str
    languages: List[str] = field(default_factory=list)

@dataclass
class VoiceGroup:
    """音色分组"""
    group: str
    options: List[VoiceOption] = field(default_factory=list)

@dataclass
class TTSConfig:
    """TTS配置类"""
    # 火山引擎配置
    app_id: str = ""
    access_token: str = ""
    resource_id: str = "volc.service_type.10029"
    ws_url: str = "wss://openspeech.bytedance.com/api/v3/tts/bidirection"
    max_size: int = 1000000000
    
    # 音频配置
    format: str = "mp3"
    sample_rate: int = 24000
    enable_timestamp: bool = False
    speech_rate: float = 1.0
    loudness_rate: float = 1.0
    emotion: str = ""
    emotion_scale: float = 1.0
    
    # 音色配置
    default_speaker: str = "zh_male_beijingxiaoye_emo_v2_mars_bigtts"  # 北京小爷
    voices: List[VoiceGroup] = field(default_factory=list) # 新增音色列表
    
    # 会话配置
    user_id: str = "default_user"
    namespace: str = "default_namespace"
    
    # 处理参数
    disable_markdown_filter: bool = True
    disable_emoji_filter: bool = True
    enable_language_detector: bool = True
    silence_duration: int = 0
    explicit_language: str = ""


@dataclass
class AudioProcessingConfig:
    """音频处理配置"""
    enable_enhancement: bool = True
    enable_normalization: bool = True
    sample_format: str = "int16"
    channel_layout: str = "mono"


@dataclass
class LoggingConfig:
    """日志配置"""
    level: str = "INFO"
    format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"


@dataclass
class WebSocketConfig:
    """WebSocket配置"""
    max_message_size: int = 10485760  # 10MB
    ping_interval: Optional[int] = None
    ping_timeout: int = 30


@dataclass
class FrontendConfig:
    """前端配置"""
    enable_cors: bool = True
    allowed_origins: List[str] = field(default_factory=lambda: ["*"])
    static_files: str = "static"


@dataclass
class CacheConfig:
    """缓存配置"""
    enable_cache: bool = True
    cache_dir: str = "cache"
    cache_size: int = 100
    cache_ttl: int = 3600


@dataclass
class SecurityConfig:
    """安全配置"""
    max_text_length: int = 5000
    rate_limit: int = 100
    enable_auth: bool = False


@dataclass
class MonitoringConfig:
    """监控配置"""
    enable_metrics: bool = True
    metrics_port: int = 8004
    health_check: bool = True


@dataclass
class AppConfig:
    """应用总配置"""
    server: ServerConfig = field(default_factory=ServerConfig)
    tts: TTSConfig = field(default_factory=TTSConfig)
    audio_processing: AudioProcessingConfig = field(default_factory=AudioProcessingConfig)
    logging: LoggingConfig = field(default_factory=LoggingConfig)
    websocket: WebSocketConfig = field(default_factory=WebSocketConfig)
    frontend: FrontendConfig = field(default_factory=FrontendConfig)
    cache: CacheConfig = field(default_factory=CacheConfig)
    security: SecurityConfig = field(default_factory=SecurityConfig)
    monitoring: MonitoringConfig = field(default_factory=MonitoringConfig)


class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config_file: Optional[str] = None):
        self.config_file = config_file or "config/tts_config.yaml"
        self.config: Optional[AppConfig] = None
        self._load_dotenv()

    def _load_dotenv(self):
        """加载.env文件"""
        if _dotenv_available:
            env_file = Path(".env")
            if env_file.exists():
                load_dotenv(env_file)
                logger.info(f"已加载环境变量文件: {env_file}")
            else:
                logger.debug("未找到.env文件，跳过加载")
        else:
            logger.debug("python-dotenv未安装，跳过.env文件加载")

    def load_config(self) -> AppConfig:
        """加载配置文件"""
        config_path = Path(self.config_file)
        
        if not config_path.exists():
            logger.warning(f"配置文件不存在: {config_path}，使用默认配置")
            self.config = AppConfig()
            self._save_default_config(config_path)
            return self.config
        
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config_data = yaml.safe_load(f)
            
            self.config = self._parse_config(config_data)
            self._load_env_variables()
            self._validate_config()
            
            logger.info(f"配置文件加载成功: {config_path}")
            return self.config
            
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}，使用默认配置")
            self.config = AppConfig()
            return self.config
    
    def _parse_config(self, config_data: Dict[str, Any]) -> AppConfig:
        """解析配置数据"""
        config = AppConfig()
        
        # 解析服务器配置
        if 'server' in config_data:
            server_data = config_data['server']
            config.server = ServerConfig(
                host=server_data.get('host', config.server.host),
                port=server_data.get('port', config.server.port),
                debug=server_data.get('debug', config.server.debug)
            )
        
        # 解析TTS配置
        if 'tts' in config_data:
            tts_data = config_data['tts']
            
            # 火山引擎配置
            volcengine_data = tts_data.get('volcengine', {})
            volcengine_config = VolcengineConfig(
                app_id=volcengine_data.get('app_id', ''),
                access_token=volcengine_data.get('access_token', ''),
                resource_id=volcengine_data.get('resource_id', 'volc.megatts.default'),
                ws_url=volcengine_data.get('ws_url', 'wss://openspeech.bytedance.com/api/v1/tts/ws_binary')
            )
            
            # 音频参数配置
            audio_data = tts_data.get('audio', {})
            audio_config = AudioConfig(
                format=audio_data.get('format', 'mp3'),
                sample_rate=audio_data.get('sample_rate', 24000),
                enable_timestamp=audio_data.get('enable_timestamp', False),
                speech_rate=audio_data.get('speech_rate', 1.0),
                loudness_rate=audio_data.get('loudness_rate', 1.0),
                emotion=audio_data.get('emotion', ''),
                emotion_scale=audio_data.get('emotion_scale', 1.0)
            )
            
            # 处理参数配置
            processing_data = tts_data.get('processing', {})
            processing_config = ProcessingConfig(
                disable_markdown_filter=processing_data.get('disable_markdown_filter', True),
                disable_emoji_filter=processing_data.get('disable_emoji_filter', True),
                enable_language_detector=processing_data.get('enable_language_detector', True),
                silence_duration=processing_data.get('silence_duration', 0),
                explicit_language=processing_data.get('explicit_language', '')
            )
            
            # 连接参数配置
            connection_data = tts_data.get('connection', {})
            connection_config = ConnectionConfig(
                timeout=connection_data.get('timeout', 30),
                max_retries=connection_data.get('max_retries', 3),
                retry_delay=connection_data.get('retry_delay', 1)
            )
            
            config.tts = TTSConfig(
                app_id=volcengine_config.app_id,
                access_token=volcengine_config.access_token,
                resource_id=volcengine_config.resource_id,
                ws_url=volcengine_config.ws_url,
                format=audio_config.format,
                sample_rate=audio_config.sample_rate,
                enable_timestamp=audio_config.enable_timestamp,
                speech_rate=audio_config.speech_rate,
                loudness_rate=audio_config.loudness_rate,
                emotion=audio_config.emotion,
                emotion_scale=audio_config.emotion_scale,
                default_speaker=tts_data.get('default_voice', 'zh_female_xiaoxue_moon_bigtts'),
                voices=self._parse_voices(tts_data.get('voices', [])), # 解析音色列表
                user_id=tts_data.get('user_id', 'default_user'),
                namespace=tts_data.get('namespace', 'default_namespace'),
                disable_markdown_filter=processing_config.disable_markdown_filter,
                disable_emoji_filter=processing_config.disable_emoji_filter,
                enable_language_detector=processing_config.enable_language_detector,
                silence_duration=processing_config.silence_duration,
                explicit_language=processing_config.explicit_language
            )
        
        # 解析音频处理配置
        if 'audio_processing' in config_data:
            ap_data = config_data['audio_processing']
            config.audio_processing = AudioProcessingConfig(
                enable_enhancement=ap_data.get('enable_enhancement', True),
                enable_normalization=ap_data.get('enable_normalization', True),
                sample_format=ap_data.get('sample_format', 'int16'),
                channel_layout=ap_data.get('channel_layout', 'mono')
            )
        
        # 解析日志配置
        if 'logging' in config_data:
            logging_data = config_data['logging']
            config.logging = LoggingConfig(
                level=logging_data.get('level', 'INFO'),
                format=logging_data.get('format', '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
            )
        
        # 解析WebSocket配置
        if 'websocket' in config_data:
            ws_data = config_data['websocket']
            config.websocket = WebSocketConfig(
                max_message_size=ws_data.get('max_message_size', 10485760),
                ping_interval=ws_data.get('ping_interval', None),
                ping_timeout=ws_data.get('ping_timeout', 30)
            )
        
        # 解析前端配置
        if 'frontend' in config_data:
            frontend_data = config_data['frontend']
            config.frontend = FrontendConfig(
                enable_cors=frontend_data.get('enable_cors', True),
                allowed_origins=frontend_data.get('allowed_origins', ['*']),
                static_files=frontend_data.get('static_files', 'static')
            )
        
        # 解析缓存配置
        if 'cache' in config_data:
            cache_data = config_data['cache']
            config.cache = CacheConfig(
                enable_cache=cache_data.get('enable_cache', True),
                cache_dir=cache_data.get('cache_dir', 'cache'),
                cache_size=cache_data.get('cache_size', 100),
                cache_ttl=cache_data.get('cache_ttl', 3600)
            )
        
        # 解析安全配置
        if 'security' in config_data:
            security_data = config_data['security']
            config.security = SecurityConfig(
                max_text_length=security_data.get('max_text_length', 5000),
                rate_limit=security_data.get('rate_limit', 100),
                enable_auth=security_data.get('enable_auth', False)
            )
        
        # 解析监控配置
        if 'monitoring' in config_data:
            monitoring_data = config_data['monitoring']
            config.monitoring = MonitoringConfig(
                enable_metrics=monitoring_data.get('enable_metrics', True),
                metrics_port=monitoring_data.get('metrics_port', 8004),
                health_check=monitoring_data.get('health_check', True)
            )
        
        return config
    
    def _parse_voices(self, voices_data: List[Dict[str, Any]]) -> List[VoiceGroup]:
        """解析音色列表数据"""
        parsed_voices = []
        for group_data in voices_data:
            options = [
                VoiceOption(
                    id=option.get('id', ''),
                    name=option.get('name', ''),
                    languages=option.get('languages', [])
                )
                for option in group_data.get('options', [])
            ]
            parsed_voices.append(VoiceGroup(group=group_data.get('group', '未知分组'), options=options))
        return parsed_voices

    def _load_env_variables(self):
        """从环境变量加载敏感配置"""
        if self.config:
            # 从环境变量读取API密钥
            env_app_id = os.getenv("VOLCENGINE_TTS_APP_ID")
            if env_app_id:
                self.config.tts.app_id = env_app_id
                logger.info("已从环境变量加载火山引擎APP ID")
                
            env_access_token = os.getenv("VOLCENGINE_TTS_ACCESS_TOKEN")
            if env_access_token:
                self.config.tts.access_token = env_access_token
                logger.info("已从环境变量加载火山引擎ACCESS TOKEN")

            # 服务器配置覆盖
            server_host = os.getenv("TTS_SERVER_HOST")
            if server_host:
                self.config.server.host = server_host
                logger.info(f"服务器主机地址已从环境变量覆盖: {server_host}")

            server_port = os.getenv("TTS_SERVER_PORT")
            if server_port:
                try:
                    self.config.server.port = int(server_port)
                    logger.info(f"服务器端口已从环境变量覆盖: {server_port}")
                except ValueError:
                    logger.warning(f"无效的服务器端口环境变量: {server_port}")

            server_debug = os.getenv("TTS_SERVER_DEBUG")
            if server_debug:
                self.config.server.debug = server_debug.lower() in ('true', '1', 'yes', 'on')
                logger.info(f"调试模式已从环境变量覆盖: {self.config.server.debug}")

            # 日志级别覆盖
            log_level = os.getenv("TTS_LOG_LEVEL")
            if log_level:
                self.config.logging.level = log_level.upper()
                logger.info(f"日志级别已从环境变量覆盖: {log_level}")

            # 安全配置覆盖
            max_text_length = os.getenv("TTS_MAX_TEXT_LENGTH")
            if max_text_length:
                try:
                    self.config.security.max_text_length = int(max_text_length)
                    logger.info(f"最大文本长度已从环境变量覆盖: {max_text_length}")
                except ValueError:
                    logger.warning(f"无效的最大文本长度环境变量: {max_text_length}")

            rate_limit = os.getenv("TTS_RATE_LIMIT")
            if rate_limit:
                try:
                    self.config.security.rate_limit = int(rate_limit)
                    logger.info(f"速率限制已从环境变量覆盖: {rate_limit}")
                except ValueError:
                    logger.warning(f"无效的速率限制环境变量: {rate_limit}")
    
    def _validate_config(self):
        """验证配置参数"""
        if not self.config:
            return
        
        # 验证服务器配置
        if not (1 <= self.config.server.port <= 65535):
            raise ValueError(f"无效的端口号: {self.config.server.port}")
        
        # 验证TTS配置
        if not self.config.tts.app_id:
            logger.warning("未设置火山引擎APP ID，请设置环境变量 VOLCENGINE_TTS_APP_ID")
            
        if not self.config.tts.access_token:
            logger.warning("未设置火山引擎ACCESS TOKEN，请设置环境变量 VOLCENGINE_TTS_ACCESS_TOKEN")
        
        # 验证音频配置
        valid_formats = ['mp3', 'wav', 'flac']
        if self.config.tts.format not in valid_formats:
            raise ValueError(f"无效的音频格式: {self.config.tts.format}")
        
        valid_sample_rates = [8000, 16000, 22050, 24000]
        if self.config.tts.sample_rate not in valid_sample_rates:
            raise ValueError(f"无效的采样率: {self.config.tts.sample_rate}")
        
        # 验证安全配置
        if self.config.security.max_text_length <= 0:
            raise ValueError(f"无效的最大文本长度: {self.config.security.max_text_length}")
            
        if self.config.security.rate_limit <= 0:
            raise ValueError(f"无效的速率限制: {self.config.security.rate_limit}")
        
        logger.info("配置验证通过")
    
    def _save_default_config(self, config_path: Path):
        """保存默认配置文件"""
        try:
            config_path.parent.mkdir(parents=True, exist_ok=True)
            
            default_config = {
                'server': {
                    'host': '0.0.0.0',
                    'port': 8003,
                    'debug': False
                },
                'tts': {
                    'volcengine': {
                        'app_id': '',
                        'access_token': '',
                        'resource_id': 'volc.megatts.default',
                        'ws_url': 'wss://openspeech.bytedance.com/api/v1/tts/ws_binary'
                    },
                    'default_voice': 'zh_female_xiaoxue_moon_bigtts',
                    'voices': [ # 默认音色列表
                        {
                            'group': '中文女声 - 多情感',
                            'options': [
                                {'id': 'zh_female_shuangkuaisisi_emo_v2_mars_bigtts', 'name': '爽快思思', 'languages': ['zh', 'en-US']},
                                {'id': 'zh_female_wanwanxiaohe_moon_bigtts', 'name': '婉婉小荷', 'languages': ['zh']},
                            ]
                        },
                        {
                            'group': '中文男声 - 多情感',
                            'options': [
                                {'id': 'zh_male_xiaohe_moon_bigtts', 'name': '小河', 'languages': ['zh']},
                            ]
                        },
                        {
                            'group': '英文音色',
                            'options': [
                                {'id': 'en_male_adam_moon_bigtts', 'name': 'Adam', 'languages': ['en-US']},
                            ]
                        }
                    ],
                    'audio': {
                        'format': 'mp3',
                        'sample_rate': 24000,
                        'enable_timestamp': False,
                        'speech_rate': 1.0,
                        'loudness_rate': 1.0,
                        'emotion': '',
                        'emotion_scale': 1.0
                    },
                    'processing': {
                        'disable_markdown_filter': True,
                        'disable_emoji_filter': True,
                        'enable_language_detector': True,
                        'silence_duration': 0,
                        'explicit_language': ''
                    },
                    'connection': {
                        'timeout': 30,
                        'max_retries': 3,
                        'retry_delay': 1
                    }
                },
                'audio_processing': {
                    'enable_enhancement': True,
                    'enable_normalization': True,
                    'sample_format': 'int16',
                    'channel_layout': 'mono'
                },
                'logging': {
                    'level': 'INFO',
                    'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
                },
                'websocket': {
                    'max_message_size': 10485760,
                    'ping_interval': None,
                    'ping_timeout': 30
                },
                'frontend': {
                    'enable_cors': True,
                    'allowed_origins': ['*'],
                    'static_files': 'static'
                },
                'cache': {
                    'enable_cache': True,
                    'cache_dir': 'cache',
                    'cache_size': 100,
                    'cache_ttl': 3600
                },
                'security': {
                    'max_text_length': 5000,
                    'rate_limit': 100,
                    'enable_auth': False
                },
                'monitoring': {
                    'enable_metrics': True,
                    'metrics_port': 8004,
                    'health_check': True
                }
            }
            
            with open(config_path, 'w', encoding='utf-8') as f:
                yaml.dump(default_config, f, default_flow_style=False, allow_unicode=True)
            
            logger.info(f"默认配置文件已保存: {config_path}")
            
        except Exception as e:
            logger.error(f"保存默认配置文件失败: {e}")
    
    def get_config(self) -> AppConfig:
        """获取配置"""
        if self.config is None:
            self.load_config()
        return self.config


# 全局配置管理器实例
config_manager = ConfigManager()


def get_config() -> AppConfig:
    """获取应用配置"""
    return config_manager.get_config()